#include "SegmentDecoder.h"
#include <iostream>

#define NAME L"Segment"

SegmentDecoder::SegmentDecoder()
{
	//cout << "[SegmentDecoder]:  constructed" << endl;
	_name = wstring(NAME);
	_err = wstring(L"NONE");
	_lsb = 0;
}
SegmentDecoder::~SegmentDecoder()
{
}
bool SegmentDecoder::Inited()
{
	//cout << "[LinerDecoder]:  Inited" << endl;
	return true;
}

void SegmentDecoder::Close()
{
	//cout << "[LinerDecoder]:  Close." << endl;
	delete this;
}

int SegmentDecoder::Decode(unsigned char *dest, int dest_buf_len, unsigned char *source, int color_depth, int column, int line, DecodeRequestStruct* args/* = 0*/)
{
	int pix_num = column * line;
	unsigned char *temp = new unsigned char[pix_num * 3];
	memset(temp, 0x00, pix_num * 3);

	if (color_depth == 8){
		for (int i = 0; i < pix_num; i++){
			temp[(pix_num - i) * 3 - 1] = source[i];
			temp[(pix_num - i) * 3 - 2] = source[i];
			temp[(pix_num - i) * 3 - 3] = source[i];
		}
	} else{
		for (int i = 0; i < pix_num; i++){
			unsigned short *_s = (unsigned short*)source;
			temp[(pix_num - i) * 3 - 1] = (_s[i] >> _lsb) & 0xff;
			temp[(pix_num - i) * 3 - 2] = temp[(pix_num - i) * 3 - 1];
			temp[(pix_num - i) * 3 - 3] = temp[(pix_num - i) * 3 - 1];
		}
	}
	if (args->UpDownReverse && args->LeftRightReverse == false)
	{
		for (int i = 0; i < line; i++)
		{
			memcpy(dest + i * column * 3, temp + (line - i - 1) * column * 3, column * 3);
		}
	}
	if (args->UpDownReverse == false && args->LeftRightReverse)
	{
		for (int i = 0; i < line; i++)
		{
			for (int j = 0; j < column; j++)
			{
				dest[(column * i + j) * 3 + 0] = temp[(column * i + (column - 1 - j)) * 3 + 0];
				dest[(column * i + j) * 3 + 1] = temp[(column * i + (column - 1 - j)) * 3 + 1];
				dest[(column * i + j) * 3 + 2] = temp[(column * i + (column - 1 - j)) * 3 + 2];
			}
		}
	}
	if (args->UpDownReverse && args->LeftRightReverse)
	{
		for (int i = 0; i < pix_num; i++){
			dest[(pix_num - i) * 3 - 1] = temp[i * 3];
			dest[(pix_num - i) * 3 - 2] = temp[i * 3 + 1];
			dest[(pix_num - i) * 3 - 3] = temp[i * 3 + 2];
		}
	}
	if (args->UpDownReverse == false && args->LeftRightReverse == false)
	{
		memcpy(dest, temp, column * line * 3);
	}
	delete[] temp;
	return 0;
}

const wchar_t* SegmentDecoder::Name()
{
	//cout << "[SegmentDecoder]:  Name" << endl;
	return _name.c_str();
}
const wchar_t* SegmentDecoder::ErrorInfo()
{
	//cout << "[SegmentDecoder]:  ErrorInfo" << endl;
	return _err.c_str();
}

void* GetDecoderPlugin(int version)
{
	if (version == DECODER_PLUGIN_INTERFACE_VERSION){
		return new SegmentDecoder();
	} else{
		return NULL;
	}
}